#!/usr/bin/env bash
# Summary: Writes specified version(s) to the specified file if the version(s) exist
# Usage: goenv version-file-write <file> <version>...
#
# If a specified version is not installed, only display an error message and abort.
# If only a single <version> `system` is specified and installed, display previous version (if any) and remove file (similar to --unset).
#
# <version> should be a string matching a Go version known to goenv.
# <version> `latest` writes the latest installed version (1.23.4).
# <version> `1` writes the latest installed major version (1.23.4).
# <version> `23` or `1.23` writes the latest installed minor version (1.23.4).
# <version> `1.23.4` writes this installed version (1.23.4).
# Run `goenv versions` for a list of available Go versions.

set -e
[ -n "$GOENV_DEBUG" ] && set -x

GOENV_VERSION_FILE="$1"
shift || true
versions=("$@")

if [ -z "$versions" ] || [ -z "$GOENV_VERSION_FILE" ]; then
  goenv-help --usage version-file-write >&2
  exit 1
fi

# Make sure the specified version(s) are installed.
# Use goenv-prefix loop logic.
if [ -n "$1" ]; then
  OLDIFS="$IFS"
  {
    IFS=:
    export GOENV_VERSION="$*"
  }
  IFS="$OLDIFS"
elif [ -z "$GOENV_VERSION" ]; then
  GOENV_VERSION="$(goenv-version-name)"
fi

GOENV_VERSIONS=()
OLDIFS="$IFS"
{
  IFS=:
  for version in ${GOENV_VERSION}; do
    if ! INSTALLED="$(goenv-installed "$version" 2>&1)"; then
      if [[ $version != "system" ]]; then
        set +e
        goenv install -q -f $version &>/dev/null
        set -e
        if [[ $? -ne 0 ]]; then
          echo "$INSTALLED" >&2
          exit 1
        fi
      fi
      # check again
      if ! INSTALLED="$(goenv-installed "$version" 2>&1)"; then
        echo "$INSTALLED" >&2
        exit 1
      fi
    fi
    GOENV_VERSIONS=("${GOENV_VERSIONS[@]}" "$INSTALLED")
  done
}
IFS="$OLDIFS"

# Special case: only system was specified and found
if [ "$1" = "system" ]; then
  if [ -f "$GOENV_VERSION_FILE" ]; then
    if previous="$(head -1 "$GOENV_VERSION_FILE" | grep -E "^[0-9]+\.[0-9]+\.[0-9]+$")"; then
      echo "goenv: using system version instead of $previous now"
    fi
    rm "$GOENV_VERSION_FILE"
  fi
else
  # Write the version out to disk.
  # Create an empty file. Using "rm" might cause a permission error.
  >"$GOENV_VERSION_FILE"
  for version in "${GOENV_VERSIONS[@]}"; do
    echo "$version" >>"$GOENV_VERSION_FILE"
  done
fi
